1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 */
6 module code_checker.process;
7 
8 import std.exception : collectException;
9 
10 import logger = std.experimental.logger;
11 
12 immutable int exitCodeSegFault = -11;
13 
14 struct RunResult {
15     int status;
16     string[] stdout;
17     string[] stderr;
18 
19     void print() @safe nothrow const scope {
20         import std.ascii : newline;
21         import std.stdio : writeln;
22 
23         foreach (l; stdout) {
24             writeln(l).collectException;
25         }
26         foreach (l; stderr) {
27             writeln(l).collectException;
28         }
29     }
30 }
31 
32 RunResult run(string[] cmd) @trusted {
33     import std.array : appender;
34     import std.algorithm : joiner, copy;
35     import std.ascii : newline;
36     import std.process : pipeProcess, tryWait, Redirect;
37     import std.stdio : writeln;
38     import core.thread : Thread;
39     import core.time : dur;
40 
41     logger.trace("run: ", cmd.joiner(" "));
42 
43     auto app_out = appender!(string[])();
44     auto app_err = appender!(string[])();
45 
46     auto p = pipeProcess(cmd, Redirect.all);
47     int exit_status = -1;
48 
49     while (true) {
50         auto pres = p.pid.tryWait;
51 
52         p.stdout.byLineCopy.copy(app_out);
53         p.stderr.byLineCopy.copy(app_err);
54 
55         if (pres.terminated) {
56             exit_status = pres.status;
57             break;
58         }
59 
60         Thread.sleep(25.dur!"msecs");
61     }
62 
63     return RunResult(exit_status, app_out.data, app_err.data);
64 }